﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using Tauren.Form.DLL.Field_FormDLL;
using Tauren.Form.DLL.Resouces;
using Tauren.Form.Entity.Config;
using Tauren.Form.Entity.Const;
using Tauren.Form.Entity.Enum;
using Tauren.Form.Entity.Global;
using Tauren.Form.Entity.Input;
using Tauren.Form.Entity.Model;
using Tauren.Form.Entity.Output;
using Tauren.Form.Infrastructure.Common;
using Tauren.Form.Infrastructure.Globals;

namespace Tauren.Form.Service.Field_FormBLL
{
    /// <summary>
    /// 表单设置
    /// </summary>
    internal class Field_FormService : Field_FromImpService
    {
        private IField_FormBusiness business;
        private LongCommon longCommon;
        public Field_FormService(IField_FormBusiness _business, IConnectionBLLBase connectionBLL, IMenuResourcesBusiness resourcesBusiness) : base(_business, connectionBLL, resourcesBusiness)
        {
            this.business = _business;
            this.ResourcesInfo = this.GetResources(GlobalConst.RESOURCES_FLAG_MODULE_FIELD_FORM_KEY);
            this.JudePrmission(GlobalConst.RESOURCES_FLAG_MODULE_FIELD_FORM_KEY.ToLower());
            longCommon = new LongCommon();
        }

        public override double VersionName => 1.0;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public override IResponseMessage Add(Field_Form_InPut data)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            if (data is null) return GlobalErrorType.GLOBAL_NOT_FOUND_INPUT_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_INPUT_DATA));
            data.AutoId = longCommon.GenerateRandomCode(6);
            ///组装表单主信息
            Entity.Model.Field_Form field_Form = new Entity.Model.Field_Form()
            {
                AutoId = data.AutoId,
                CNName = data.CNName,
                ENName = data.ENName,
                UseApplicantEmpId = data.UseApplicantEmpId,
                CurrentVersion = -1,
                Modifier = Global.EmpId,
                Creator = Global.EmpId,
                Status = (int)FormStatus.design
            };
            using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted }))
            {
                bool b = false;
                long id = business.UnRepeatAdd(field_Form);
                if (id > 0)
                {
                    List<Form_Field_Child_TableInfo> tableInfos = new List<Form_Field_Child_TableInfo>();
                    List<Form_Field_Primary_TableInfo> primary_TableInfos = new List<Form_Field_Primary_TableInfo>();
                    foreach (var item in data.Tables)
                    {
                        long prId = longCommon.GenerateRandomCode(7);
                        primary_TableInfos.Add(new Form_Field_Primary_TableInfo()
                        {
                            AutoId = prId,
                            FlowTableCode = item.FlowTableCode,
                            FormId = data.AutoId,
                            ForeignKey = item.ForeignKey,
                            TableCode = item.TableCode,
                            TableId = item.TableId
                        });
                        item.Childs.ForEach(p =>
                        {
                            tableInfos.Add(new Form_Field_Child_TableInfo()
                            {
                                AutoId = longCommon.GenerateRandomCode(7),
                                PrimaryTableId = prId,
                                FlowTableCode = p.FlowTableCode,
                                ForeignKey = p.ForeignKey,
                                TableCode = p.TableCode
                            });
                        });
                    }
                    if (primary_TableInfos.Any())
                    {
                        b = business.Add(primary_TableInfos) >= 0;
                        if (b && tableInfos.Any())
                            b = business.Add(tableInfos);
                    }
                }
                else
                    return GlobalErrorType.GLOBAL_REPEAT_CODE.Failure(this.CommonText(GlobalErrorType.GLOBAL_RES_LANGUAGE_REPEAT_NNAME_ERROR));
                if (b)
                {
                    ts.Complete();
                    return "".OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_SUCCESSINFO.ToString()));
                }
                else return GlobalErrorType.GLOBAL_SAVE_FAILURE.OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_FAILURE));
            }
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="AutoID"></param>
        /// <returns></returns>
        public override IResponseMessage Delete(long AutoID)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            var data = business.Get<Field_Form>(AutoID);
            if (data is null) return GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA));
            ///todo 此处缺少 删除时判断该表单产生数据没有。后续表单使用后补上
            data.HaveDelete = true;
            data.Status = (int)FormStatus.delete;
            data.Modifier = Global.EmpId;
            data.Modifdate = DateTime.Now;
            bool b = business.Update<Field_Form>(data);
            if (b)
                return "".OnSucceed(this.Resources(GlobalErrorType.GLOBAL_DELETE_SUCCESSINFO));
            else return GlobalErrorType.GLOBAL_DELETE_FAILURE.OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_DELETE_FAILURE));
        }

        /// <summary>
        /// 修改数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public override IResponseMessage Edit(Field_Form_InPut data)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            if (data is null) return GlobalErrorType.GLOBAL_NOT_FOUND_INPUT_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_INPUT_DATA));
            bool iscoe = business.IstTableRepeat(data.AutoId, data.CNName, data.ENName);
            if (iscoe) return GlobalErrorType.GLOBAL_REPEAT_CODE.Failure(this.CommonText(GlobalErrorType.GLOBAL_RES_LANGUAGE_REPEAT_NNAME_ERROR)); 
            var singe = business.Get<Field_Form>(data.AutoId);
            if (singe is null) return GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA));
            ///组装表单主信息 
            singe.CNName = data.CNName;
            singe.ENName = data.ENName;
            singe.Modifdate = DateTime.Now;
            singe.Modifier = Global.EmpId;
            using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted }))
            {
                bool b = business.Update(singe);
                b = business.DeleteTableInfos(singe.AutoId);
                if (b)
                {
                    List<Form_Field_Child_TableInfo> tableInfos = new List<Form_Field_Child_TableInfo>();
                    List<Form_Field_Primary_TableInfo> primary_TableInfos = new List<Form_Field_Primary_TableInfo>();
                    foreach (var item in data.Tables)
                    {
                        long prId = longCommon.GenerateRandomCode(6);
                        primary_TableInfos.Add(new Form_Field_Primary_TableInfo()
                        {
                            AutoId = prId,
                            FlowTableCode = item.FlowTableCode,
                            FormId = data.AutoId,
                            ForeignKey = item.ForeignKey,
                            TableCode = item.TableCode,
                            TableId = item.TableId
                        });
                        item.Childs.ForEach(p =>
                        {
                            tableInfos.Add(new Form_Field_Child_TableInfo()
                            {
                                AutoId = longCommon.GenerateRandomCode(6),
                                PrimaryTableId = prId,
                                FlowTableCode = p.FlowTableCode,
                                ForeignKey = p.ForeignKey,
                                TableCode = p.TableCode
                            });
                        });
                    }
                    if (primary_TableInfos.Any())
                    {
                        b = business.Add(primary_TableInfos) >= 0;
                        if (b && tableInfos.Any())
                            b = business.Add(tableInfos);
                    }
                }
                if (b)
                {
                    ts.Complete();
                    return "".OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_SUCCESSINFO.ToString()));
                }
                else return GlobalErrorType.GLOBAL_SAVE_FAILURE.OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_FAILURE));
            }
        }

        /// <summary>
        /// 获取单个数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public override IResponseMessage FirstOrDefault(long id)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            Field_Form form_Table = business.Get<Field_Form>(id);
            if (form_Table is null) return new Field_Form_OutPut() .Succeed(); 
            Field_Form_OutPut _OutPut;
            ToViewModel(form_Table, out _OutPut);
            List<TableInfo> tableInfos = business.GetAll<TableInfo>();
            if (_OutPut != null)
            {
                List<Form_Field_TableInfo_OutPut> tableInfo_OutPuts = business.GetFormFieldTableInfos(_OutPut.AutoId);
                if (tableInfo_OutPuts.Any())
                {
                    var res = tableInfo_OutPuts.Join(tableInfos, a => a.TableCode.ToLower(), b => b.TableCode.ToLower(), (a, b) =>
                    {
                        a.TableName = Global.IsChinese ? b.CNName : b.ENName;
                        return a;
                    });
                    if (res.Any())
                    {
                        res.GroupBy(o => new { o.TableCode, o.TableName, o.PrimaryKey, o.TableId }).ToList().ForEach(p =>
                         {
                             Form_Field_Primary_TableInfo_OutPut primaryInfo = new Form_Field_Primary_TableInfo_OutPut();
                             primaryInfo.TableCode = p.Key.TableCode;
                             primaryInfo.TableName = p.Key.TableName;
                             primaryInfo.ForeignKey = p.Key.PrimaryKey;
                             primaryInfo.TableId = p.Key.TableId;
                             p.Join(tableInfos, a => a.ChildTableCode.ToLower(), b => b.TableCode.ToLower(), (a, b) =>
                             {
                                 a.ChildTableName = Global.IsChinese ? b.CNName : b.ENName;
                                 return a;
                             }).ToList().ForEach(c =>
                             {
                                 primaryInfo.Childs.Add(new Form_Field_Child_TableInfo_OutPut()
                                 {
                                     TableCode = c.ChildTableCode,
                                     TableName = c.ChildTableName,
                                     ForeignKey = c.ForeignKey
                                 });
                             });
                             _OutPut.Tables.Add(primaryInfo);
                         });
                    }
                }
            } 
            return _OutPut.Succeed();
        }     

        public override IResponseMessage Pages(QueryModel queryModel)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            ///获取基础数据库中表信息
            List<TableInfo> tableInfos = business.GetAll<TableInfo>();
            TableListModel<PageField_FormTable> tableListModel = new TableListModel<PageField_FormTable>();
            List<TableListHeaderModele> Headers = new List<TableListHeaderModele>();
            Headers.Add(new TableListHeaderModele() { Key = "rowNo", Name = CommonText("rowNo"), Width = 50, Align = "center", Fixed = true });
            Headers.Add(new TableListHeaderModele() { Key = "autoId", Name = CommonText("autoid"), Width = 70, Hide = true, Type = "primary_key", Align = "center", SorTable = SortType.custom.ToString(), Fixed = true });
            Headers.Add(new TableListHeaderModele() { Key = "cnName", Name = CommonText("thcnname"), Align = "left", IsOperation = true, Fixed = true });
            Headers.Add(new TableListHeaderModele() { Key = "enName", Name = CommonText("thenname"), Align = "left", Fixed = true });
            Headers.Add(new TableListHeaderModele() { Key = "currentVersion", Name = Resources("currentversion"), Width = 160, Align = "left", Fixed = true, SorTable = SortType.custom.ToString() });
            Headers.Add(new TableListHeaderModele() { Key = "dic_Status", Name = CommonText("thstate"), IsTag = true, Width = 100, Align = "center", SorTable = SortType.custom.ToString() });
            Headers.Add(new TableListHeaderModele() { Key = "dic_Creator", Name = CommonText("diccreator"), Width = 120, Align = "center" });
            Headers.Add(new TableListHeaderModele() { Key = "dic_Creatdate", Name = CommonText("diccreatdate"), Width = 160, Align = "center" });
            long Total = 0;
            List<PageField_FormTable> Data = business.Pages(queryModel, out Total);

            if (Data.Any())
            {
                Data.ForEach(o =>
                {
                    o.Row_Style = ((FormStatus)o.Status) != FormStatus.delete && ((FormStatus)o.Status) != FormStatus.unloaded ? "" : "danger";
                    o.Dic_Creator = EmpDictionary.ContainsKey(o.Creator) ? EmpDictionary[o.Creator] : "";
                    o.Dic_Creatdate = o.Creatdate.Value.ToString(GlobalConst.DATE_FORMAT_SECONDS);
                    o.Dic_Status = this.Resources($"formstatus{((FormStatus)o.Status) + ""}");
                    o.Operations = new List<SystemButton>();
                    if (Global.IsAdmin && (Buttons is null || !Buttons.Any()))
                    {
                        BuliderButtons(o.Operations, o.CurrentVersion + "", o.AutoId, ButtomType.edit);
                        BuliderButtons(o.Operations, o.CurrentVersion + "", o.AutoId, ButtomType.set);
                        BuliderButtons(o.Operations, o.CurrentVersion + "", o.AutoId, ButtomType.detaile);
                        BuliderButtons(o.Operations, o.CurrentVersion + "", o.AutoId, ButtomType.delete);
                        if (o.Status == (int)FormStatus.installed)
                        {
                            BuliderButtons(o.Operations, o.CurrentVersion + "", o.AutoId, ButtomType.unloaded);
                        }
                        if (o.Status == (int)FormStatus.unloaded)
                        {
                            BuliderButtons(o.Operations, o.CurrentVersion + "", o.AutoId, ButtomType.enable);
                        }
                    }
                    else
                    {
                        if (Buttons.Any(o => o.Location == ButtomLocation.center.ToString() && o.Value == ButtomType.edit.ToString()))
                            BuliderButtons(o.Operations, o.CurrentVersion + "", o.AutoId, ButtomType.edit);
                        if (Buttons.Any(o => o.Location == ButtomLocation.center.ToString() && o.Value == ButtomType.set.ToString()))
                            BuliderButtons(o.Operations, o.CurrentVersion + "", o.AutoId, ButtomType.set);
                        if (Buttons.Any(o => o.Location == ButtomLocation.center.ToString() && o.Value == ButtomType.detaile.ToString()))
                            BuliderButtons(o.Operations, o.CurrentVersion + "", o.AutoId, ButtomType.detaile);
                        if (Buttons.Any(o => o.Location == ButtomLocation.center.ToString() && o.Value == ButtomType.delete.ToString()))
                            BuliderButtons(o.Operations, o.CurrentVersion + "", o.AutoId, ButtomType.delete);
                        if (o.Status == (int)FormStatus.installed && Buttons.Any(o => o.Location == ButtomLocation.center.ToString() && o.Value == ButtomType.unloaded.ToString()))
                        {
                            BuliderButtons(o.Operations, o.CurrentVersion + "", o.AutoId, ButtomType.unloaded);
                        }
                        if (o.Status == (int)FormStatus.unloaded && Buttons.Any(o => o.Location == ButtomLocation.center.ToString() && o.Value == ButtomType.unloaded.ToString()))
                        {
                            BuliderButtons(o.Operations, o.CurrentVersion + "", o.AutoId, ButtomType.enable);
                        }
                    }
                });
            }
            tableListModel.Body = Data;
            tableListModel.Total = Total;
            tableListModel.Header = Headers;
            if (Global.IsAdmin && (Buttons is null || !Buttons.Any()))
            {
                BuliderButtons(tableListModel.Operations, "", 0, ButtomType.add);
            }
            else
            {
                if (Buttons.Any(o => o.Value == ButtomType.add.ToString()))
                    BuliderButtons(tableListModel.Operations, "", 0, ButtomType.add);
            }
            return tableListModel.Succeed();
        }
        /// <summary>
        /// 是否卸载表单
        /// </summary>
        /// <param name="AutoID"></param>
        /// <returns></returns>
        public override IResponseMessage Uninstall(long AutoID)
        {

            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            var data = business.Get<Field_Form>(AutoID);
            if (data is null) return GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA));
            data.Status = (FormStatus)data.Status == FormStatus.unloaded ? (int)FormStatus.installed : (int)FormStatus.unloaded;
            data.Modifier = Global.EmpId;
            data.Modifdate = DateTime.Now;
            bool b = business.Update<Field_Form>(data);
            if (b) return "".OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_SUCCESSINFO.ToString()));
            else return GlobalErrorType.GLOBAL_SAVE_FAILURE.OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_FAILURE));
        }

    }
}
